package com.demo.webapp.ui;

import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.demo.webapp.ui.DisplayerConfig;
import com.demo.webapp.ui.RepositoryBuilder;
import com.demo.webapp.ui.RepositoryBuilderDelegate;
import com.demo.webapp.ui.RepositoryResource;

public class ComponentBuilderPorcess implements BeanPostProcessor, ApplicationContextAware {

	private ApplicationContext applicationContext;
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)	throws BeansException {
		
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		//dasa
		if (bean instanceof RepositoryBuilder ){
			if (bean instanceof RepositoryBuilderDelegate) {
				return bean;
			}
			RepositoryBuilder builder = (RepositoryBuilder) bean;
			Object target = builder.pop();
			//目标类实现组件资源接口
			if (target.getClass().isAssignableFrom(RepositoryResource.class)) {
				List<DisplayerConfig> configs = ((RepositoryResource) target).getMapping().getDisplayerConfig();
				if (configs != null) {
					for(DisplayerConfig config : configs) {
						BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.genericBeanDefinition(config.getType());
						//以名字自动写入属性
						beanBuilder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
						//设置bean使用范围
						beanBuilder.setScope(BeanDefinition.SCOPE_PROTOTYPE);
						beanBuilder.addPropertyValue("name", config.getName());
						//beanBuilder.addPropertyValue("type", Displayer.Type.menu.toString());
						//builder.addPropertyValue(name, value)
						//applicationContext.
						
						if (applicationContext instanceof BeanDefinitionRegistry) {
							BeanDefinitionRegistry registry = (BeanDefinitionRegistry) applicationContext;
							registry.registerBeanDefinition(config.getType(), beanBuilder.getBeanDefinition());
						}
					}
				}
			}
		}
		return bean;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}
}
